import tensorflow as tf

"""
   MODEL: 训练得到的模型。
   graph：保存网络结构（包含各个节点（op、node name、input、output））和各个节点上的数值。
   Saver(variable)：加载变量 、Session(ema后的v值)
   graph_def：导出n网络架构中的ode信息。
    
"""


def network_structure():
    """
    构建网络结构
    :return:
    """
    v1 = tf.Variable(.9, dtype=tf.float32, name= 'v')
    v2 = tf.Variable(1.2, tf.float32)
    v3 = v1 + v2
    return v3


def save_model(file_path):
    """
    保存计算得到的模型
    :param file_path:
    :return:
    """
    v = network_structure()
    saver = tf.train.Saver()
    with tf.Session() as session:
        session.run(tf.global_variables_initializer())
        session.run(v)
        saver.save(session, file_path)


def read_model(file_path):
    """
    读取计算得到模型
    :param file_path:
    :return:
    """
    v = network_structure()
    saver = tf.train.Saver()

    with tf.Session() as sess:

        # 加载模型，不用初始化变量
        saver.restore(sess, file_path)
        print(sess.run(v))


def read_graph_meta(meta_file_path, model_file_path):
    """
        加载 meta_graph (网络结构 network_structure)
    :param meta_file_path:
    :return:
    """
    saver = tf.train.import_meta_graph(meta_file_path)

    with tf.Session() as sess:
        saver.restore(sess, model_file_path)

        # node:0 得到node节点的第一个值。 add为graph相加操作节点。
        print(sess.run(tf.get_default_graph().get_tensor_by_name('add:0')))


def load_variable(file):
    """
      加载文件中的参数
    :param file:
    :return:
    """
    var1 = tf.Variable(0, dtype=tf.float32, name='v')
    saver = tf.train.Saver({'v': var1})
    with tf.Session() as sess:
        saver.restore(sess, file)
        print(sess.run(var1))


def move_average_save(file):
    """
        将平滑平均值保存的saver中
    :param file:
    :return:
    """
    v = tf.Variable(1, dtype=tf.float32, name='v')
    ema = tf.train.ExponentialMovingAverage(0.99)
    move_op = ema.apply(tf.global_variables())

    saver = tf.train.Saver()

    for variable in tf.global_variables():
        print(variable)

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(sess.run([v, ema.average(v)]))

        # 赋值后并执行，计算平滑平均数值
        sess.run(tf.assign(v, 110))
        sess.run(move_op)
        print(sess.run([v, ema.average(v)]))
        # saver.save(sess, file)


def move_average_load(file):
    """
     加载平滑平均apply后的v值
    :param file:
    :return:
    """

    v = tf.Variable(22.2, dtype=tf.float32, name='v')
    ema = tf.train.ExponentialMovingAverage(0.8)
    print(ema.variables_to_restore())
    saver = tf.train.Saver(ema.variables_to_restore())

    with tf.Session() as sess:
        saver.restore(sess, file)
        print(sess.run(v))


def graph_output_node_save(file):
    """
    graph 节点保存（变量转为常量）
    :param file:
    :return:
    """
    v = network_structure()
    with tf.Session() as session:
        session.run(tf.global_variables_initializer())
        print(session.run(v))
        graph_def = tf.get_default_graph().as_graph_def()
        graph_output_def = tf.graph_util.convert_variables_to_constants(session, graph_def, ["add"])
        with tf.gfile.GFile(file, 'wb') as f:
            f.write(graph_output_def.SerializeToString())


def graph_input_node_save(file):
    """
     读取node add 输出的常量，
    :param file:
    :return:
    """
    with tf.gfile.FastGFile(file, 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())

        result = tf.import_graph_def(graph_def, return_elements=['add:0'])

        with tf.Session() as sess:
            print(sess.run(result))



def main(argv=None):
    file = '../data/model/save_model.test'
    meta_file = '../data/model/save_model.test.meta'
    file2 = '../data/model/save_model.test2'
    file_out_node = '../data/model/save_model.test3'
    graph_input_node_save(file_out_node)


if __name__ == '__main__':
    tf.app.run()